package cn.lumora.core.security.rea;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * RSA加解密工具类，提供基于公钥加密和私钥解密的方法
 */
public class RSACipherUtil {
    
    /**
     * 使用公钥进行加密
     * 
     * @param data 要加密的数据
     * @param publicKeyStr Base64编码的公钥字符串
     * @return Base64编码的加密结果
     * @throws Exception 加密过程中发生的任何异常
     */
    public static String encryptWithPublicKey(String data, String publicKeyStr) throws Exception {
        // 解码Base64格式的公钥数据
        byte[] decodedKey = Base64.getDecoder().decode(publicKeyStr);
        
        // 创建公钥对象
        PublicKey publicKey = KeyFactory.getInstance("RSA")
                .generatePublic(new X509EncodedKeySpec(decodedKey));
        
        // 创建并初始化Cipher对象，使用RSA/ECB/PKCS1Padding填充模式
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        // 执行加密操作并进行Base64编码
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }
    
    /**
     * 使用私钥进行解密
     * 
     * @param encryptedData Base64编码的加密数据
     * @param privateKeyStr Base64编码的私钥字符串
     * @return 解密后的原始数据
     * @throws Exception 解密过程中发生的任何异常
     */
    public static String decryptWithPrivateKey(String encryptedData, String privateKeyStr) throws Exception {
        // 解码Base64格式的私钥数据
        byte[] decodedKey = Base64.getDecoder().decode(privateKeyStr);
        
        // 创建私钥对象
        PrivateKey privateKey = KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(decodedKey));
        
        // 创建并初始化Cipher对象，使用RSA/ECB/PKCS1Padding填充模式
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        // 执行解密操作并转换为字符串
        return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedData)));
    }
}
